#ifndef  RECOVERY_FS_FILE_FILE_H
#define  RECOVERY_FS_FILE_FILE_H

#include <cstdint>
#include <cstddef>
#include <string>
#include "recovery/ErrnoStatus.h"

namespace recovery {
namespace fs {
namespace file {


class FileDescriptor;


class File {
public:
    explicit File(const std::string & path) : _path(path) {}
    File(const File & f) : _path(f.path()) {}
    virtual ~File() {}

    virtual bool exist() const;
    virtual ErrnoStatus remove() const;
    virtual ErrnoStatus touch() const; 
    virtual ErrnoStatus truncate(size_t size = 0) const;
    virtual ErrnoStatus size(size_t & sz) const;
    
    virtual ErrnoStatus openForAppend(FileDescriptor & fd) const;
    virtual ErrnoStatus openForRandomRead(FileDescriptor & fd) const;
    virtual ErrnoStatus openForRandomWrite(FileDescriptor & fd) const;

    virtual ErrnoStatus createForAppend(FileDescriptor & fd) const;
    virtual ErrnoStatus createForRandomWrite(FileDescriptor & fd) const;

    virtual ErrnoStatus close(const FileDescriptor & fd) const;
    virtual ErrnoStatus skip(const FileDescriptor & fd, const int64_t offset) const;
    virtual ErrnoStatus seekBegin(const FileDescriptor & fd, const size_t offset) const;
    virtual ErrnoStatus seekEnd(const FileDescriptor & fd, const int64_t offset) const;
    virtual ErrnoStatus read(const FileDescriptor & fd, uint8_t * buf, const size_t len, size_t & readBytes) const;
    virtual ErrnoStatus append(const FileDescriptor & fd, const uint8_t * buf, const size_t len, size_t & appendedBytes) const;
    virtual ErrnoStatus write(const FileDescriptor & fd, const uint8_t * buf, const size_t len, size_t & writedBytes) const;

    virtual ErrnoStatus positionedRead(const FileDescriptor & fd, const size_t offset, uint8_t * buf, const size_t len, size_t & readBytes) const;
    virtual ErrnoStatus positionedAppend(const FileDescriptor & fd, const size_t offset, const uint8_t * buf, const size_t len, size_t & appendedBytes) const;
    virtual ErrnoStatus positionedWrite(const FileDescriptor & fd, const size_t offset, const uint8_t * buf, const size_t len, size_t writedBytes) const;

    virtual ErrnoStatus sync(const FileDescriptor & fd) const;

    const std::string & path() const {
        return _path;
    }
    
private:
    ErrnoStatus posixSeek(const FileDescriptor & fd, const int64_t offset, int whence) const;

private:
    const std::string _path;
};

} //end of namespace file
} //end of namespace fs
} //end of namespace recovery

#endif   /* RECOVERY_FS_FILE_FILE_H */
